"""API实现类"""
import json
import time
import logging
import requests
import sseclient
from typing import Dict, Any, Optional, Union
from logger_manager import LoggerManager
from config_manager import ConfigManager
from requests.exceptions import RequestException, Timeout, ConnectionError


class ChatAPIError(Exception):
    """Chat API 异常基类"""
    pass


class NetworkError(ChatAPIError):
    """网络相关异常"""
    pass


class APIError(ChatAPIError):
    """API 响应异常"""
    pass


class ResponseHandler:
    """响应处理器"""

    def __init__(self, logger: logging.Logger, typing_speed: float = 0.01):
        self.logger = logger
        self.typing_speed = typing_speed

    def process_stream(self, response: requests.Response) -> tuple[str, Optional[str]]:
        """处理流式响应"""
        conversation_id = None
        complete_response = []
        try:
            client = sseclient.SSEClient(response)
            print("\nAssistant: ", end='', flush=True)
            for event in client.events():
                # 处理不同类型的事件
                if event.event == "message_end":
                    self.logger.debug("收到消息结束事件 message_end")
                    break
                elif event.event == "tts_message_end":
                    self.logger.debug("收到 TTS 音频流结束事件 tts_message_end")
                    break
                elif event.data == '[DONE]':
                    self.logger.debug("收到结束标记[DONE]")
                    break

                try:
                    data = json.loads(event.data)
                    if data:
                        self.logger.info(
                            f"\n{'=' * 50}\n流式响应内容: {json.dumps(data, ensure_ascii=False, indent=2)}\n{'=' * 50}")
                        if 'answer' in data:
                            complete_response.append(data['answer'])
                            for char in data['answer']:
                                print(char, end='', flush=True)
                                time.sleep(self.typing_speed)
                        if 'conversation_id' in data and data['conversation_id']:
                            conversation_id = data['conversation_id']
                except json.JSONDecodeError:
                    continue
            
            # 记录完整的响应内容
            complete_text = ''.join(complete_response)
            return complete_text, conversation_id
        except Exception as e:
            self.logger.error(f"处理流式响应失败: {str(e)}")
            raise APIError(f"处理响应失败: {str(e)}")

    def process_blocking(self, response: requests.Response) -> tuple[str, Optional[str]]:
        """处理阻塞式响应"""
        try:
            response_data = response.json()
            # 记录响应日志
            self.logger.info(
                f"\n{'=' * 50}\n响应内容: {json.dumps(response_data, ensure_ascii=False, indent=2)}\n{'=' * 50}")
            answer = response_data.get('answer', '')
            conversation_id = response_data.get('conversation_id')
            return answer, conversation_id
        except json.JSONDecodeError as e:
            self.logger.error(f"解析响应JSON失败: {str(e)}")
            raise APIError(f"无效的响应格式: {str(e)}")


class ChatAPI:
    def __init__(self):
        config = ConfigManager()
        self.api_key = config.get_config('chat_api_key')
        self.base_url = config.get_config('base_url')
        self.user_id = config.get_config('user_id', 'default_user')
        self.timeout = int(config.get_config('request_timeout', '30'))
        self.typing_speed = float(config.get_config('typing_speed', '0.01'))

        self.logger = LoggerManager.get_logger()
        self.response_handler = ResponseHandler(self.logger, self.typing_speed)
        self.conversation_id: Optional[str] = None

    def _get_headers(self) -> Dict[str, str]:
        return {
            'Authorization': f'Bearer {self.api_key}',
            'Content-Type': 'application/json'
        }

    def _log_request(self, method: str, url: str, payload: Dict[str, Any]) -> None:
        self.logger.info(
            f"\n{'=' * 50}\n请求方法: {method}\n请求URL: {url}\n请求内容: {json.dumps(payload, ensure_ascii=False, indent=2)}\n{'=' * 50}")

    def _log_response(self, response_data: Dict[str, Any]) -> None:
        self.logger.info(
            f"\n{'=' * 50}\n响应内容: {json.dumps(response_data, ensure_ascii=False, indent=2)}\n{'=' * 50}")

    def _check_response(self, response: requests.Response) -> None:
        """检查响应状态"""
        if response.status_code >= 400:
            try:
                error_data = response.json()
                error_message = error_data.get('message', '未知错误')
            except json.JSONDecodeError:
                error_message = response.text
            raise APIError(f"API错误 (状态码: {response.status_code}): {error_message}")

    def chat_message(self, message: str, stream: bool = True) -> None:
        """对话型应用API - 发送消息"""
        url = f'{self.base_url}/chat-messages'
        payload = {
            'inputs': {},
            'query': message,
            'response_mode': 'streaming' if stream else 'blocking',
            'user': self.user_id
        }

        if self.conversation_id:
            payload['conversation_id'] = self.conversation_id

        self._log_request('POST', url, payload)

        try:
            response = requests.post(
                url,
                json=payload,
                headers=self._get_headers(),
                stream=stream,
                timeout=self.timeout
            )

            self._check_response(response)

            if stream:
                answer, new_conversation_id = self.response_handler.process_stream(response)
                if new_conversation_id:
                    self.conversation_id = new_conversation_id
                print(f"\nAssistant: {answer}\n")  # 显示完整答案
            else:
                answer, new_conversation_id = self.response_handler.process_blocking(response)
                if new_conversation_id:
                    self.conversation_id = new_conversation_id
                print(f"\nAssistant: {answer}\n")

        except Timeout:
            self.logger.error("请求超时")
            print("\n错误: 请求超时，请稍后重试")
        except ConnectionError as e:
            self.logger.error(f"网络连接错误: {str(e)}")
            print("\n错误: 网络连接失败，请检查网络连接")
        except RequestException as e:
            self.logger.error(f"请求异常: {str(e)}")
            print(f"\n错误: 请求失败 - {str(e)}")
        except ChatAPIError as e:
            self.logger.error(f"API错误: {str(e)}")
            print(f"\n错误: {str(e)}")
        except Exception as e:
            self.logger.error(f"未知错误: {str(e)}")
            print(f"\n错误: 发生未知错误，请联系管理员")

    def start_new_conversation(self) -> None:
        """开始新的会话"""
        self.conversation_id = None

    def get_conversation_id(self) -> Optional[str]:
        """获取当前会话ID"""
        return self.conversation_id
